package com.xbongbong.rule.rules;

import lombok.Data;
import org.jeasy.rules.api.*;
import org.jeasy.rules.spel.SpELRule;
import org.springframework.expression.BeanResolver;
import org.springframework.expression.ParserContext;

/**
 * SpEL语法规则
 * 规则判断逻辑由调用方处理传入
 * <p>eg:</p>
 * <pre class="code">
 *     SpelXbbRule&lt;JSONObject&gt; spelXbbRule = new SpelXbbRule<>();
 *     spelXbbRule.setRuleId("spel_1");
 *     spelXbbRule.setCondition("#JSONObject.get('text_4').contains('123')");
 *     spelXbbRule.setBeanResolver(new BeanFactoryResolver(applicationContext));
 *     spelXbbRule.setXbbAction({
 *         new XbbAction&lt;JSONObject&gt;() {
 *                &#064;Override
 *                public void action(JSONObject jsonObject) {
 *                     System.out.println("===================rule匹配！！！！");
 *                }
 *            });
 *     </pre>
 *     <p>
 *       用法和spEL语法规则测试：
 *       SpElFireTest,
 *       spElTest
 *     </p>
 * @author zheng.li
 *
 * @param <T>
 */
@SuppressWarnings("AlibabaRemoveCommentedCode")
@Data
public class SpelXbbRule<T> implements XbbRule<T> {

    /**
     * 规则的唯一标识
     */
    protected String ruleId;

    /**
     * 优先级
     * （easyRule的规则优先级，当规则的优先级超过ruleEngine的阈值（priorityThreshold）时，则忽略此规则）
     */
    protected Integer priority = 1;

    /**
     * SpEL 条件语句
     */
    private String condition;

    /**
     * SpEL 规则执行语句
     * （目前不使用此参数，用xbbAction或xbbRuleEngine中的listeners代替）
     */
    @Deprecated
    private String action;

    /**
     * 规则触发逻辑类
     * 一般处理逻辑可能对于解释语言来说比较难写或者难维护，提供java方式的处理类
     */
    protected XbbAction<T> xbbAction;

    /**
     * 可以通过BeanResolver 用给定@名称查找 bean 并为其返回相应的实例。
     */
    protected BeanResolver beanResolver;

    @Override
    public Rule toEasyRule() {
        return new SpELRule(beanResolver).name(ruleId).priority(priority)
                .when(buildCondition());
    }

    @Override
    public XbbAction<T> getXbbAction() {
        return xbbAction;
    }

    /**
     * 构造condition
     * @return String
     */
    private String buildCondition() {
        // 使用 ‘#{’ 和 ‘}’ 将语句包起来
        return  ParserContext.TEMPLATE_EXPRESSION.getExpressionPrefix() + condition
                + ParserContext.TEMPLATE_EXPRESSION.getExpressionSuffix();
    }

    /**
     * 构造action
     * @return String
     */
    @Deprecated
    private String buildAction() {
        // 使用 ‘#{’ 和 ‘}’ 将语句包起来
        return   ParserContext.TEMPLATE_EXPRESSION.getExpressionPrefix() + action
                + ParserContext.TEMPLATE_EXPRESSION.getExpressionSuffix();
    }



}
